package com.example.waibao.service.impl;

import cn.hutool.setting.Setting;
import com.aliyun.oss.model.GetObjectRequest;
import com.sun.scenario.Settings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.autoconfigure.h2.H2ConsoleProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class SseEmitterServer {


    //private static Map<String,Map<String, SseEmitter>> sseCache = new ConcurrentHashMap<>();
    private static Map<String, SseEmitter> sseCache = new ConcurrentHashMap<>();

    //用来群发指定学校的
    private static Map<Integer,Map<String, SseEmitter>> sseCache_school = new ConcurrentHashMap<>();


    //获取全部的sseClientId
    public static List<String> getIds(){

        return new ArrayList<>(sseCache.keySet());

    }

    //连接
    public SseEmitter subscribe(String sseClientId) {
//        if (!NotNullCheck.str(sseClientId)) {
//            return null;
//        }
        SseEmitter sseEmitter = null;
        SseEmitter getClientEmitter = sseCache.get(sseClientId);
        if (getClientEmitter == null || !checkSseConnectAlive(getClientEmitter)) {
            // 生存时间设置 默认30s,设置永久存活
            sseEmitter = new SseEmitter(0L);
            // 设置前端的重试时间
            try {
                sseEmitter.send(SseEmitter.event().reconnectTime( 30).data("连接成功"));
                sseCache.put(sseClientId, sseEmitter);
//                //用来群发指定学校的
//                sseCache_school.put(school_id,new ConcurrentHashMap<>());
//                sseCache_school.get(school_id).put(sseClientId, sseEmitter);
                System.out.println("add " + sseClientId);
                sseEmitter.onTimeout(() -> {
                    System.out.println(sseClientId + "超时");
                    sseCache.remove(sseClientId);
                });
                sseEmitter.onCompletion(() -> System.out.println("已关闭连接：" + sseClientId));
            } catch (Exception e) {

                System.err.println(e.getMessage());
            }
        } else {
            System.out.println("已存在！");
            sseEmitter = getClientEmitter;
        }
        return sseEmitter;
    }
    //为了群发消息做了修改的接口
//    public SseEmitter subscribe(String sseClientId,int school_id) {
////        if (!NotNullCheck.str(sseClientId)) {
////            return null;
////        }
//        SseEmitter sseEmitter = null;
//        SseEmitter getClientEmitter = sseCache.get(sseClientId);
//        if (getClientEmitter == null || !checkSseConnectAlive(getClientEmitter)) {
//            // 生存时间设置 默认30s,设置永久存活
//            sseEmitter = new SseEmitter(0L);
//            // 设置前端的重试时间
//            try {
//                sseEmitter.send(SseEmitter.event().reconnectTime( 30).data("连接成功"));
//                sseCache.put(sseClientId, sseEmitter);
//                //用来群发指定学校的
//                sseCache_school.put(school_id,new ConcurrentHashMap<>());
//                sseCache_school.get(school_id).put(sseClientId, sseEmitter);
//                System.out.println("add " + sseClientId);
//                sseEmitter.onTimeout(() -> {
//                    System.out.println(sseClientId + "超时");
//                    sseCache.remove(sseClientId);
//                });
//                sseEmitter.onCompletion(() -> System.out.println("已关闭连接：" + sseClientId));
//            } catch (Exception e) {
//
//                System.err.println(e.getMessage());
//            }
//        } else {
//            System.out.println("已存在！");
//            sseEmitter = getClientEmitter;
//        }
//        return sseEmitter;
//    }

    public boolean sendOneClientMessage(String sseClientId,Object msg) throws IOException {
        SseEmitter sseEmitter = sseCache.get(sseClientId);
        if (sseEmitter != null && checkSseConnectAlive(sseEmitter)) {
            sseEmitter.send(SseEmitter.event().data(msg));
            return true;
        } else {
            return false;
        }
    }


    //群发学校通知
//    public void sendAllClientMsg2(Object msg, int school_id) {
//        if (sseCache_school.get(school_id) != null && !sseCache_school.get(school_id).isEmpty()) {
//            sseCache_school.get(school_id).entrySet().forEach(sseEmitterSet -> {
//                String sseClientId = sseEmitterSet.getKey();
//                SseEmitter sseEmitter = sseEmitterSet.getValue();
//                if (sseEmitter != null) {
//                    if (checkSseConnectAlive(sseEmitter)) {
//                        SseEmitter.SseEventBuilder sseEventBuilder = SseEmitter
//                                .event()
//                                .data(msg)
//                                .reconnectTime( 30);
//                        try {
//                            sseEmitter.send(sseEventBuilder);
//                        } catch (Exception e) {
//                            System.err.println("SSE check sseClientId send error:" + sseClientId);
//                        }
//                    } else {
//                        sseEmitter.complete();
//                        sseCache.remove(sseClientId);
//                        System.out.println("SSE check sseClientId offline:" + sseClientId);
//                    }
//                }
//            });
//        }
//    }

    //群发所有软件
    public void sendAllClientMsg(Object msg) {
        if (sseCache != null && !sseCache.isEmpty()) {
            sseCache.entrySet().forEach(sseEmitterSet -> {
                String sseClientId = sseEmitterSet.getKey();
                SseEmitter sseEmitter = sseEmitterSet.getValue();
                if (sseEmitter != null) {
                    if (checkSseConnectAlive(sseEmitter)) {
                        SseEmitter.SseEventBuilder sseEventBuilder = SseEmitter
                                .event()
                                .data(msg)
                                .reconnectTime( 30);
                        try {
                            sseEmitter.send(sseEventBuilder);
                        } catch (Exception e) {
                            System.err.println("SSE check sseClientId send error:" + sseClientId);
                        }
                    } else {
                        sseEmitter.complete();
                        sseCache.remove(sseClientId);
                        System.out.println("SSE check sseClientId offline:" + sseClientId);
                    }
                }
            });
        }
    }

    public boolean close(String sseClientId) {
        SseEmitter sseEmitter = sseCache.get(sseClientId);
        if (sseEmitter != null) {
            System.out.println("SSE active close connection :" + sseClientId);
            sseEmitter.complete();
            sseCache.remove(sseClientId);
            return true;
        } else {
            return false;
        }
    }

    public boolean checkSseConnectAlive(SseEmitter sseEmitter) {
        if (sseEmitter == null) {
            return false;
        }
        return !(Boolean) getFieldInstance(sseEmitter, "sendFailed") &&
                !(Boolean) getFieldInstance(sseEmitter, "complete");
    }

    public static Object getFieldInstance(Object obj, String fieldPath) {
        String fields[] = fieldPath.split("#");
        for (String field : fields) {
            obj = getField(obj, obj.getClass(), field);
            if (obj == null) {
                return null;
            }
        }

        return obj;
    }

    public static Object getField(Object obj, Class<?> clazz, String fieldName) {
        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
            try {
                Field field;
                field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
                return field.get(obj);
            } catch (Exception e) {
            }
        }

        return null;
    }


    public void aliveCheck(ApplicationArguments args) throws Exception {
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                sendAllClientMsg("Check Alive");
            }
        }, 3 * 1000, 3 * 1000);
    }



}
